/**
 * Octopus, an XMMS2 client.
 * Copyright (C) 2014 Octopus Team
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

namespace Octopus {
	public abstract class MedialibTracklist : Object  {
		public string album         { get; protected set; default = ""; }
		public string artist        { get; protected set; default = ""; }
		public string name          { get; set; default = ""; }
		public int    partofset     { get; protected set; default = 0; }
		public string performer     { get; protected set; default = ""; }
		public string picture_front { get; protected set; default = ""; } //notify::picture-front
		public string searchquery   { get; set; default = ""; }
		public bool   stored_in_medialib { get; construct set; default = false; } //notify::stored-in-medialib

		public signal void add_track (Track t);
		public signal void add_track_finished (int track_count);

		public MedialibTracklist () {
			Object ();
		}

		public void requestTracklist () {
			if (   (album == "")
			    && (artist == "")
			    && (name == "")
			    && (performer == "")
			    && (searchquery == "")
			   ) {
				GLib.warning ("warning, unable to query: no data");
				add_track_finished (0);
				return;
			}

			var intersection = new Xmms.Collection (Xmms.CollectionType.INTERSECTION);
			var universe = Xmms.Collection.universe ();

			if (album != "") {
				GLib.debug ("album: %s", album);
				var equalsAlbum = new Xmms.Collection (Xmms.CollectionType.EQUALS);
				equalsAlbum.attribute_set ("field", "album");
				equalsAlbum.attribute_set ("value", album);
				equalsAlbum.add_operand (universe);
				intersection.add_operand (equalsAlbum);
			}

			if (partofset != 0) {
				GLib.debug ("partofset: %i", partofset);
				var equalsPartofset = new Xmms.Collection (Xmms.CollectionType.EQUALS);
				equalsPartofset.attribute_set ("field", "partofset");
				equalsPartofset.attribute_set ("value", "%d".printf (partofset));
				equalsPartofset.add_operand (universe);
				intersection.add_operand (equalsPartofset);
			}

			if (performer != "") {
				GLib.debug ("performer: %s", performer);
				var equalsPerformer = new Xmms.Collection (Xmms.CollectionType.EQUALS);
				equalsPerformer.attribute_set ("field", "performer");
				equalsPerformer.attribute_set ("value", performer);
				equalsPerformer.add_operand (universe);
				intersection.add_operand (equalsPerformer);
			} else if (artist != "") {
				GLib.debug ("artist: %s", artist);
				var equalsArtist = new Xmms.Collection (Xmms.CollectionType.EQUALS);
				equalsArtist.attribute_set ("field", "artist");
				equalsArtist.attribute_set ("value", artist);
				equalsArtist.add_operand (universe);
				intersection.add_operand (equalsArtist);
			}

			if (name != "") {
				Xmms.Collection collection;
				if (this is Playlist) {
					Xmms.Collection.parse ("in:\"Playlists/" + name + "\"", out collection);
				} else {
					Xmms.Collection.parse ("in:\"" + name + "\"", out collection);
				}
				intersection.add_operand (collection);
			}

			if (searchquery != "") {
				Xmms.Collection collection;
				Xmms.Collection.parse (searchquery, out collection);
				intersection.add_operand (collection);
			}

			var order = new Xmms.Value.from_list ();
			if (   (this is Album)
			    || (this is CollectionAlbum)) {
				order.list_append (new Xmms.Value.from_string ("partofset"));
				order.list_append (new Xmms.Value.from_string ("tracknr"));
			} else {
				order.list_append (new Xmms.Value.from_string ("artist"));
				order.list_append (new Xmms.Value.from_string ("title"));
			}
			var fetch = new Xmms.Value.from_list ();
			fetch.list_append (new Xmms.Value.from_string ("album"));
			fetch.list_append (new Xmms.Value.from_string ("artist"));
			fetch.list_append (new Xmms.Value.from_string ("duration"));
			fetch.list_append (new Xmms.Value.from_string ("id"));
			fetch.list_append (new Xmms.Value.from_string ("picture_front"));
			fetch.list_append (new Xmms.Value.from_string ("title"));
			fetch.list_append (new Xmms.Value.from_string ("tracknr"));
			fetch.list_append (new Xmms.Value.from_string ("url"));

			Global.get ().get_xmms_client ().get_xmms ().coll_query_infos (
			  intersection, //Collection coll
			  order,        //Xmms.Value order
			  0,            //uint limit_start = 0
			  0,            //uint limit_len = 0
			  fetch,        //Xmms.Value? fetch = null
			  fetch         //Xmms.Value? group = null
			  ).notifier_set (on_coll_query_trackList);
		}

		protected bool on_coll_query_trackList(Xmms.Value values) {
			unowned Xmms.ListIter iter;
			int counter = 0;

			if (values.is_error()) {
				unowned string error = "unknown";
				values.get_error(out error);
				GLib.warning ("warning, failed to query (%s)", error);
				return true;
			}

			values.get_list_iter(out iter);
			if (!iter.valid()) add_track_finished (0); //empty iterator; no query result

			for (iter.first(); iter.valid(); iter.next()) {
				unowned Xmms.Value entry;

				iter.entry(out entry);

				Track t = new Track ();
				t.set_values (entry);
				counter++;
				add_track (t);
			}
			add_track_finished (counter);
			return true;
		}
	}
}
